home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / System / Swatch / Development / swatch 1.2 / swatch INIT / (driver open INIT) / drvr.open.INIT.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-15  |  4.4 KB  |  203 lines  |  [TEXT/KAHL]

  1. /**
  2.  
  3.     open.init.c
  4.     Copyright (c) 1990, joe holt
  5.  
  6.  **/
  7.  
  8.  
  9. /**-----------------------------------------------------------------------------
  10.  **
  11.  **    Compilation Flags
  12.  **
  13.  **/
  14.  
  15. /**
  16.  
  17.     MULTI_SEGMENT generates code which is needed to init a multi-segmented
  18.     driver.  Single-segment drivers can be inited also, so there is no logical
  19.     requirement to ever turn this off, except where code size is a concern.
  20.  
  21.  **/
  22.  
  23. #define MULTI_SEGMENT    1
  24.  
  25.  
  26. /**-----------------------------------------------------------------------------
  27.  **
  28.  **    Headers
  29.  **
  30.  **/
  31.  
  32. #include <types.h>
  33. #include "ShowINIT.h"
  34.  
  35.  
  36. /**-----------------------------------------------------------------------------
  37.  **
  38.  **    Private Constants
  39.  **
  40.  **/
  41.  
  42. /**
  43.  
  44.     UNIT_ENTRIES_NEEDED and FIRST_POSSIBLE_UNIT are used when determining the
  45.     driver reference number for our driver.  We assign our driver reference
  46.     number dynamically, looking at FIRST_POSSIBLE_UNIT and on up for an unused
  47.     number.  We increase the unit table size to UNIT_ENTRIES_NEEDED if
  48.     there aren't that many unit numbers, using a technique gleaned from ADSP.
  49.     This occurs on Mac Pluses and Mac SEs, where the unit table defaults to
  50.     forty-eight entries, which doesn't leave any room for custom drivers like
  51.     ourself.
  52.  
  53. **/
  54.  
  55. #define UNIT_ENTRIES_NEEDED        (64)
  56. #define FIRST_POSSIBLE_UNIT        (48)
  57.  
  58. #define INSTALLED_ICN_            (128)
  59. #define NOT_INSTALLED_ICN_        (129)
  60. #define ERROR_INSTALLING_ICN_    (130)
  61.  
  62.  
  63. /**-----------------------------------------------------------------------------
  64.  **
  65.  **    Private Functions
  66.  **
  67.  **/
  68.  
  69. int main(void);
  70.  
  71. main()
  72. {
  73.     char driver_name[128];
  74.     register Handle h;
  75.     register DCtlHandle *d;
  76.     DCtlPtr dp;
  77.     register int16 the_ID, i, icon;
  78.     int16 res_ID;
  79.     IOParam open_driver_PB;
  80.     KeyMap keymap;
  81.  
  82.     asm {
  83.                 move.l    A4, -(A7)
  84.                 movea.l    A0, A4
  85.     }
  86.  
  87.     /**
  88.      **   If mouse button or shift key is down, don't install
  89.      **/
  90.  
  91.     GetKeys( &keymap );
  92.     if ( Button() || (keymap.Key[1] & 1 /* shift key */) ) {
  93.         icon = NOT_INSTALLED_ICN_;
  94.         goto exit;
  95.     }
  96.  
  97.     icon = ERROR_INSTALLING_ICN_;
  98.     SetResLoad( FALSE );
  99.     if ( !( h = Get1IndResource( 'DRVR', 1 ) ) )
  100.         goto exit;
  101.  
  102.     SetResAttrs( h, resSysHeap | resLocked );
  103.     ReleaseResource( h );
  104.  
  105.  
  106. /**
  107.  
  108.     Pick an unused driver reference number for our DRVR and renumber the resource
  109.     to use this new reference number.  We first increase the number of entries
  110.     in the unit table if less than UNIT_ENTRIES_NEEDED, then begin looking at
  111.     FIRST_POSSIBLE_UNIT.  This strategy was copied from the ADSP INIT.
  112.  
  113.  **/
  114.  
  115.     SetResLoad( TRUE );
  116.     h = Get1IndResource( 'DRVR', 1 );
  117.     GetResInfo( h, NULL, NULL, driver_name );
  118.     DetachResource( h );
  119.     if ( UnitNtryCnt < UNIT_ENTRIES_NEEDED ) {
  120.         asm {
  121. ;
  122. ;    Increase the number of available entries in the unit table.
  123. ;
  124.                 move.w    #UNIT_ENTRIES_NEEDED * 4, D0
  125.                 _NewPtr    SYS+CLEAR
  126.                 bne        @exit
  127.     
  128.                 move    SR, -(A7)
  129.                 move    #0x2600, SR
  130.                 movea.l    A0, A1
  131.                 movea.l    UTableBase, A0
  132.                 move.w    UnitNtryCnt, D0
  133.                 mulu    #4, D0
  134.                 _BlockMove
  135.                 _DisposPtr
  136.                 move.l    A1, UTableBase
  137.                 move.w    #UNIT_ENTRIES_NEEDED, UnitNtryCnt
  138.                 move    (A7)+, SR
  139.         }
  140.     }
  141.  
  142.     d = (DCtlHandle *) UTableBase + FIRST_POSSIBLE_UNIT;
  143.     for ( the_ID = FIRST_POSSIBLE_UNIT; *d && the_ID <= UnitNtryCnt; ++d, ++the_ID );
  144.     if ( the_ID > UnitNtryCnt )
  145.         goto exit;
  146.  
  147.     asm {
  148.                 move.w    the_ID, D0
  149.                 not.w    D0
  150.                 movea.l    (h), A0
  151.                 dc.w    0xA43D                ; _DrvrInstall 4
  152.                 bne        @exit
  153.     }
  154.  
  155.     HLock( *d );
  156.     dp = **d;
  157.     dp->dCtlDriver = (Ptr) h;
  158.     dp->dCtlFlags = **(int16 **) h | 0x40;
  159.  
  160. /**
  161.  
  162.     Now set the resources which THINK C uses for drivers to load into the System
  163.     Heap as locked, also.  We especially want to lock down any DCOD resources
  164.     because the THINK C segment loader does a MoveHHi() on 'em when first loaded,
  165.     which is not a good idea in the System Heap at INIT time.
  166.  
  167.  **/
  168.  
  169.     the_ID <<= 5;
  170.  
  171.     SetResLoad( FALSE );
  172.     if ( ( h = Get1IndResource( 'DATA', 1 ) ) ) {
  173.         SetResInfo( h, the_ID | 0xC000, NULL );
  174.         SetResAttrs( h, resSysHeap | resLocked );
  175.         ReleaseResource( h );
  176.     }
  177.  
  178. #if MULTI_SEGMENT
  179.     for ( i = Count1Resources( 'DCOD' ); i; --i ) {
  180.         if ( !( h = Get1IndResource( 'DCOD', i ) ) )
  181.             goto exit;
  182.         GetResInfo( h, &res_ID, NULL, NULL );
  183.         SetResInfo( h, the_ID | (res_ID & 0xF01F), NULL );
  184.         SetResAttrs( h, resSysHeap | resLocked );
  185.         ReleaseResource( h );
  186.     }
  187. #endif
  188.  
  189.     SetResLoad( TRUE );
  190.  
  191.     open_driver_PB.ioNamePtr = (StringPtr) driver_name;
  192.     open_driver_PB.ioPermssn = 0;
  193.     if ( !PBOpen( &open_driver_PB, FALSE ) )
  194.         icon = INSTALLED_ICN_;
  195.     
  196. exit:
  197.     SetResLoad( TRUE );
  198.     ShowINIT( icon, -1 );
  199.     asm {
  200.                 move.l    (A7)+, A4
  201.     }
  202. }
  203.